#include "ipcShm.hpp"

static void client()
{
    key_t key = ftok(PATHNAME, PROJID);
    if (key < 0)
    {
        perror("ftok");
        exit(1);
    }

    int shmid = shmget(key, SHMSIZE, IPC_CREAT | 0666);
    if (shmid < 0)
    {
        perror("shmget");
        exit(2);
    }

    fprintf(stdout, "key: %d shmid: %d\n", key, shmid);

    void *shm_ptr = shmat(shmid, nullptr, 0);
    if (shm_ptr == reinterpret_cast<void *>(-1))
    {
        perror("shmat");
        exit(3);
    }

    int n = 0;
    char *ptr = static_cast<char *>(shm_ptr);
    while (true)
    {
        // SHM_LOCK只保证自己进程内部的同步互斥
        // 不像管道一样保存进程内部及进程之间的同步互斥
        fprintf(stdout, "lock\n");
        shmctl(shmid,SHM_LOCK,nullptr);
        for (int i = 0; i < 5; ++i)
        {
            ptr[n++] = 'a' + n;
            ptr[n] = '\0';
            sleep(1);
        }
        fprintf(stdout, "unlock\n");
        shmctl(shmid,SHM_UNLOCK,nullptr);
    }

    int ret = shmdt(shm_ptr);
    if (ret < 0)
    {
        perror("shmat");
        exit(4);
    }
}

int main()
{
    client();
    return 0;
}